package com.bub.pay.framework.wrap.aspect;

import com.bub.pay.framework.common.base.Cause;
import com.bub.pay.framework.common.base.Module;
import com.bub.pay.framework.common.entity.model.RespObject;
import com.bub.pay.framework.common.exception.GlobalException;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class ResponseWrapper {
    @Value("${spring.application.name}")
    private String module;

    private final Logger logger = LoggerFactory.getLogger(ResponseWrapper.class);

    @Around("execution(public * com.bub.pay.*.controller.*.*(..))&&!@annotation(com.bub.pay.framework.wrap.annotation.EscapeWrapper)&&!@within(com.bub.pay.framework.wrap.annotation.EscapeWrapper)")
    protected Object wrapper(ProceedingJoinPoint joinPoint) {
        RespObject br;
        try {
            Object data = joinPoint.proceed();
            br = new RespObject<>(RespObject.SUCCESS_CODE, RespObject.SUCCESS_MSG, data);
        } catch (Throwable e) {
            logger.error("wrapper error", e);
            if (e instanceof AuthenticationException) {
                logger.error(e.getMessage(), e);
                if (e instanceof IncorrectCredentialsException) throw new GlobalException(Cause.error_login);
                AuthenticationException authenticationException = (AuthenticationException) e;
                Throwable throwable = authenticationException.getCause();
                if (throwable instanceof GlobalException) {
                    throw (GlobalException) throwable;
                }
                throw new GlobalException(Module.which(module), Cause.unknown, e);
            } else if (e instanceof IllegalArgumentException) {
                throw new GlobalException((Module.which(module).getSn() * GlobalException.CARRY) + Cause.params_fail.getCode(), e.getMessage());
            } else if (e instanceof GlobalException)
                throw (GlobalException) e;
            logger.error(e.getMessage(), e);
            throw new GlobalException(Module.which(module), Cause.unknown, e);
        }
        return br;
    }

}
